package com.bff.slimserver.musicjukebox.ui;

import com.bff.bjj.ui.BJJFrame;
import com.bff.bjj.ui.ConnectionErrorDialog;
import com.bff.bjj.ui.LAFChangeEvent;
import com.bff.bjj.ui.LAFChangeListener;
import com.bff.bjj.ui.UpdateSplashDialog;
import com.bff.slimserver.music.MusicObjects;
import com.bff.slimserver.musicjukebox.lib.events.PlayerChosenEvent;
import com.bff.bjj.utils.Utils;
import com.bff.slimserver.musicjukebox.lib.JukeboxProperties;
import com.bff.slimserver.musicjukebox.lib.events.PlayerChosenListener;
import com.bff.slimserver.musicjukebox.lib.events.SettingsChangedEvent;
import com.bff.slimserver.musicjukebox.lib.events.SettingsChangedListener;
import com.bff.bjj.ui.component.BJJPanel;
import com.bff.bjj.utils.Resources.LABEL_KEY;
import com.bff.slimserver.musicjukebox.ui.settings.SettingsPanel;
import com.bff.startup.StartUpProperties;
import com.bff.startup.StartupFrame;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.Rectangle;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.bff.slimserver.SlimPlayer;
import org.bff.slimserver.SlimPlaylist;
import org.bff.slimserver.events.ConnectionChangeEvent;
import org.bff.slimserver.events.ConnectionChangeListener;
import org.bff.slimserver.events.FavoriteChangeEvent;
import org.bff.slimserver.events.FavoriteChangeListener;
import org.bff.slimserver.events.PlayerChangeEvent;
import org.bff.slimserver.events.PlayerChangeListener;
import org.bff.slimserver.events.PlaylistChangeEvent;
import org.bff.slimserver.events.PlaylistChangeListener;
import org.bff.slimserver.events.SavedPlaylistChangeEvent;
import org.bff.slimserver.events.SavedPlaylistChangeListener;
import org.bff.slimserver.exception.SlimConnectionException;
import org.bff.slimserver.exception.SlimException;
import org.bff.slimserver.musicobjects.SlimPlaylistItem;

/**
 *
 * @author  Bill
 */
public class MainFramePlayer
        extends BJJFrame
        implements PlaylistChangeListener,
        PlayerChangeListener,
        WindowListener,
        SettingsChangedListener,
        ConnectionChangeListener,
        FavoriteChangeListener,
        PlayerChosenListener,
        LAFChangeListener,
        SavedPlaylistChangeListener {

    private JukeboxProperties jp;
    private SlimPlaylist playlist;
    private SlimPlayer player;
    private SongInfoPanel songInfoPanel;
    private RetractPanel retractPanel;
    private PlaylistPanel playlistPanel;
    private JPanel playerpanelThin;
    private JPanel leftPanel;
    private JPanel guitarPanel;
    private boolean retracting;
    private static final int PLAYLIST_TAB_INDEX = 2;
    private JFrame parent;
    private TrayIcon trayIcon;
    private JSplitPane jsp;
    private int currentPanelType;
    private static JPanel minimizePanel;
    private static JFrame frame;
    private static int oldX;
    private static int oldY;
    private static Dimension oldSize;
    private ConnectionErrorDialog connectionErrorDialog;
    private boolean currentlyRetracting;
    private boolean loaded;

    /** Creates new form MainFrame */
    public MainFramePlayer(SplashScreen sp) {
        parent = this;
        sp.setProgressbarMax(100);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setIconImage(Utils.createImageIcon(getClass(), "/resources/slimserver/bjjicontray.jpg", "bjj image").getImage());

        try {
            this.jp = JukeboxProperties.getInstance();

            playlistPanel = new PlaylistPanel();
            playlistPanel.hideButtons();

            initComponents();

            player = jp.getPlayer();
            playlist = jp.getPlaylist();

            jp.getSlimMonitor().addPlaylistChangeListener(this);
            jp.getSlimMonitor().addSavedPlaylistChangeListener(this);

            sp.setProgressBarLabel(" Loading song panel...");
            sp.setProgressbarValue(10);

            if (jp.getPlaylist().getItemCount() > 0) {
                this.songInfoPanel = new SongInfoPanel((SlimPlaylistItem) jp.getPlaylist().getCurrentItem(), jp.isShowCoverArt(), true);
            } else {
                this.songInfoPanel = new SongInfoPanel(jp.isShowCoverArt());
            }

            loadedSongPanel = true;

            if (jp.isShowCoverArt()) {
                this.songInfoPanel.setPreferredSize(new Dimension(400, 475));
            } else {
                this.songInfoPanel.setPreferredSize(new Dimension(400, 275));
            }
            currentSongPanel.add(songInfoPanel);

            sp.setProgressBarLabel(" Loading search panel...");
            sp.setProgressbarValue(20);

            searchTabPanel.add(new SearchPanel(), BorderLayout.CENTER);
            loadedSearchPanel = true;

            sp.setProgressBarLabel(" Loading explorer panel...");
            sp.setProgressbarValue(40);
            artistTabPanel.add(new ExplorerPanel(jp.isUseTreeExplorer()), BorderLayout.CENTER);
            loadedExplorerPanel = true;

            sp.setProgressBarLabel(" Loading playlist manager panel...");
            sp.setProgressbarValue(50);
            loadPlaylistManagerPanel();

            sp.setProgressBarLabel(" Loading player manager panel...");
            sp.setProgressbarValue(60);
            loadPlayerManagerPanel();

            if (jp.isShowAlbumsPanel()) {
                sp.setProgressBarLabel(" Loading album panel...");
                sp.setProgressbarValue(70);

                loadAlbumPanel();
            } else {
                mainTabbedPane.remove(albumTabPanel);
                loadedAlbumPanel = true;
            }

            if (jp.isShowNewMusicPanel()) {
                sp.setProgressBarLabel(getResource(LABEL_KEY.NEW_MUSIC_LOADING));
                sp.setProgressbarValue(75);

                loadNewMusicPanel();
            } else {
                mainTabbedPane.remove(newMusicTabPanel);
                loadedNewMusicPanel = true;
            }

            sp.setProgressBarLabel(" Loading folder panel...");
            sp.setProgressbarValue(80);
            loadFolderPanel();

            if (jp.getClientType() == JukeboxProperties.CLIENT_PLAYER_LEFT) {
                currentPanelType = JukeboxProperties.CLIENT_PLAYER_LEFT;
                createLeftPlayer(sp);
            } else {
                currentPanelType = JukeboxProperties.CLIENT_PLAYER_TOP;
                createTopPanel(sp);
            }

            playerpanelThin = new PlayerPanelThin();
            loadedPlayerPanel = true;
            add(playerpanelThin, BorderLayout.NORTH);

            addWindowListener(this);

            setVisible(true);
            sp.toFront();

            if (retractPanel != null) {
                loadRetractPanel();
            }

            checkForUpdate();

            if (jp.isShowGuitarPanel()) {
                if (guitarPanel == null) {
                    guitarPanel = new GuitarPanel();
                    loadedGuitarPanel = true;
                }
                mainTabbedPane.remove(settingsTabPanel);
                mainTabbedPane.addTab("Guitar", guitarPanel);
                mainTabbedPane.addTab("Settings", settingsTabPanel);
            } else {
                if (guitarPanel != null) {
                    mainTabbedPane.remove(guitarPanel);
                }
            }

            jp.addSettingsChangedListener(this);
            jp.getSlimMonitor().addPlayerChangeListener(this);
            jp.getSlimMonitor().addConnectionChangeListener(this);
            jp.getFavoritesPlugin().addFavoriteChangeListener(this);
            jp.addPlayerChosenListener(this);

            playlist.addPlaylistChangeListener(new PlaylistChangeListener() {

                @Override
                public void playlistChanged(PlaylistChangeEvent event) {
                    slimPlaylistChanged(event);
                }
            });

            loadPlayerManagerMini();

        } catch (Exception e) {
            sp.setStopped(true);
            e.printStackTrace();
            new ErrorDialog(this, "An unexpected error has occurred", e);
        } finally {
            sp.setStopped(true);
        }

        GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
        jPanel6.add(playlistPanel.getPlaylistAlternativeButtonPanel(), gridBagConstraints);

        loadRadiosPanel();

        mainTabbedPane.remove(musicServicesTabPanel);

        loadFavoritesPanel();

        loadPodcastPanel();

        if (jp.isTrayAlways()) {
            loadIntoTray();
        }

        playlistPanel.getPlaylistAlternativeButtonPanel().setVisible(true);
        frame = this;
        minimizePanel = jPanel1;
        setLoaded(true);
        ((SettingsPanel) settingsPanel).getLAFPanel().addLAFChangeListener(this);
    }

    private void createLeftPlayer(SplashScreen sp) {

        leftPanel = new BJJPanel();
        leftPanel.setLayout(new BorderLayout());

        mainTabbedPane.setTabPlacement(javax.swing.JTabbedPane.TOP);

        if (sp != null) {
            sp.setProgressBarLabel(" Loading player panel...");
            sp.setProgressbarValue(80);
        }

        if (sp != null) {
            sp.setProgressBarLabel(" Loading playlist panel...");
            sp.setProgressbarValue(90);
        }

        if (playlistPanel != null) {
            playlistTabPanel.remove(playlistPanel);
        } else {
            playlistPanel = new PlaylistPanel();
        }

        playlistPanel.setPlaylistButtonPanelGrid();

        playlistTabPanel.remove(infoPanel);
        playlistTabPanel.add(infoPanel, BorderLayout.CENTER);

        leftPanel.add(playlistPanel, BorderLayout.CENTER);

        jPanel1.remove(mainTabbedPane);
        remove(jPanel1);

        leftPanel.setMinimumSize(new Dimension(400, 800));

        jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, mainTabbedPane);
        jsp.setDividerLocation(400);
        add(jsp, BorderLayout.CENTER);

        if (sp != null) {
            sp.setProgressbarValue(100);
        }
    }

    private void createTopPanel(SplashScreen sp) throws SlimException {

        if (jsp != null) {
            jsp.remove(leftPanel);
            jsp.remove(mainTabbedPane);
            remove(jsp);
            jPanel1.add(mainTabbedPane, BorderLayout.CENTER);
            add(jPanel1, BorderLayout.CENTER);
        }

        mainTabbedPane.setTabPlacement(javax.swing.JTabbedPane.LEFT);
        if (leftPanel != null) {
            remove(leftPanel);
        }

        if (playlistPanel == null) {

            if (sp != null) {
                sp.setProgressBarLabel(" Loading playlist panel...");
                sp.setProgressbarValue(80);
            }
            new Thread(new Runnable() {

                @Override
                public void run() {
                    playlistPanel = new PlaylistPanel();
                    playlistTabPanel.add(playlistPanel, BorderLayout.CENTER);
                }
            }).start();
        } else {
            playlistTabPanel.add(playlistPanel, BorderLayout.CENTER);
        }

        if (sp != null) {
            sp.setProgressBarLabel(" Loading player panel...");
            sp.setProgressbarValue(90);
        }

        setRetracting(true);
        songPanelRetract.setVisible(true);
        songPanelRetract.setPreferredSize(new Dimension(200, 100));
        retractPanel = new RetractPanel(songPanelRetract, RetractPanel.BOTTOM_UP);


        new Thread(new Runnable() {

            @Override
            public void run() {
                while (!loadedPodPanel && jPanel6.getSize().getHeight() < 1 && songInfoPanel.getSize().getHeight() < 1) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }

                try {
                    Thread.sleep(10000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                }

                if (!jp.isShowCoverArt()
                        || (infoPanel.getSize().getHeight() - (jPanel6.getSize().getHeight() + songInfoPanel.getSize().getHeight())) >= 120) {
                    GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
                    gridBagConstraints.gridx = 0;
                    gridBagConstraints.gridy = 2;
                    gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
                    StatPanel p = new StatPanel();
                    p.setColumnLayout();
                    p.setPreferredSize(new Dimension(300, 80));
                    jPanel6.add(p, gridBagConstraints);
                }
            }
        }).start();

        repaint();

        if (sp != null) {
            sp.setProgressbarValue(100);
        }
    }

    private void checkPlayer() {
        if (jp.isStopOnExit()) {
            try {
                getPlayer().stop();
            } catch (SlimConnectionException ex) {
                Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jPanel1 = new BJJPanel();
        mainTabbedPane = new javax.swing.JTabbedPane();
        playlistTabPanel = new BJJPanel();
        infoPanel = new BJJPanel();
        currentSongPanel = new BJJPanel();
        jPanel6 = new BJJPanel();
        searchTabPanel = new BJJPanel();
        artistTabPanel = new BJJPanel();
        albumTabPanel = new BJJPanel();
        newMusicTabPanel = new BJJPanel();
        folderTabPanel = new BJJPanel();
        savedPlaylistTabPanel = new BJJPanel();
        savedPlaylistPanel = new BJJPanel();
        playerTabPanel = new BJJPanel();
        favoritesTabPanel = new javax.swing.JPanel();
        podcastTabPanel = new javax.swing.JPanel();
        radiosTabPanel = new javax.swing.JPanel();
        musicServicesTabPanel = new javax.swing.JPanel();
        settingsTabPanel = new BJJPanel();
        jPanel2 = new BJJPanel();
        settingsPanel = new SettingsPanel();
        jPanel4 = new BJJPanel();
        songPanelRetract = new SongRetractInfoPanel();

        jMenu1.setText("Menu");
        jMenuBar1.add(jMenu1);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Bill's Jammin' Jukebox");

        jPanel1.setLayout(new java.awt.BorderLayout());

        mainTabbedPane.setTabPlacement(javax.swing.JTabbedPane.LEFT);

        playlistTabPanel.setLayout(new java.awt.BorderLayout());

        infoPanel.setMaximumSize(new java.awt.Dimension(500, 2147483647));
        infoPanel.setLayout(new java.awt.BorderLayout());

        currentSongPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Currently Playing"));
        currentSongPanel.setMinimumSize(new java.awt.Dimension(450, 550));
        currentSongPanel.setPreferredSize(new java.awt.Dimension(450, 550));
        infoPanel.add(currentSongPanel, java.awt.BorderLayout.CENTER);

        jPanel6.setLayout(new java.awt.GridBagLayout());
        infoPanel.add(jPanel6, java.awt.BorderLayout.SOUTH);

        playlistTabPanel.add(infoPanel, java.awt.BorderLayout.EAST);

        mainTabbedPane.addTab("Playlist", playlistTabPanel);

        searchTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab("Search", searchTabPanel);

        artistTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab("Explorer", artistTabPanel);

        albumTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab("Albums", albumTabPanel);

        newMusicTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab(getResource(LABEL_KEY.NEW_MUSIC_TAB_TITLE), newMusicTabPanel);

        folderTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab("Folder", folderTabPanel);

        savedPlaylistTabPanel.setLayout(new java.awt.BorderLayout());

        savedPlaylistPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Saved Playlists"));
        savedPlaylistPanel.setLayout(new java.awt.BorderLayout());
        savedPlaylistTabPanel.add(savedPlaylistPanel, java.awt.BorderLayout.CENTER);

        mainTabbedPane.addTab("Playlists", savedPlaylistTabPanel);

        playerTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab("Players", playerTabPanel);

        favoritesTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab("Favorites", favoritesTabPanel);

        podcastTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab("Podcasts", podcastTabPanel);

        radiosTabPanel.setLayout(new java.awt.BorderLayout());
        mainTabbedPane.addTab("Radios", radiosTabPanel);
        mainTabbedPane.addTab("Services", musicServicesTabPanel);

        jPanel2.setLayout(new java.awt.GridBagLayout());
        jPanel2.add(settingsPanel, new java.awt.GridBagConstraints());

        jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.LINE_AXIS));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanel2.add(jPanel4, gridBagConstraints);

        settingsTabPanel.add(jPanel2);

        mainTabbedPane.addTab("Settings", settingsTabPanel);

        jPanel1.add(mainTabbedPane, java.awt.BorderLayout.CENTER);
        jPanel1.add(songPanelRetract, java.awt.BorderLayout.EAST);

        getContentPane().add(jPanel1, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel albumTabPanel;
    private javax.swing.JPanel artistTabPanel;
    private javax.swing.JPanel currentSongPanel;
    private javax.swing.JPanel favoritesTabPanel;
    private javax.swing.JPanel folderTabPanel;
    private javax.swing.JPanel infoPanel;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JTabbedPane mainTabbedPane;
    private javax.swing.JPanel musicServicesTabPanel;
    private javax.swing.JPanel newMusicTabPanel;
    private javax.swing.JPanel playerTabPanel;
    private javax.swing.JPanel playlistTabPanel;
    private javax.swing.JPanel podcastTabPanel;
    private javax.swing.JPanel radiosTabPanel;
    private javax.swing.JPanel savedPlaylistPanel;
    private javax.swing.JPanel savedPlaylistTabPanel;
    private javax.swing.JPanel searchTabPanel;
    private javax.swing.JPanel settingsPanel;
    private javax.swing.JPanel settingsTabPanel;
    private javax.swing.JPanel songPanelRetract;
    // End of variables declaration//GEN-END:variables

    private void setSongInfo(SlimPlaylistItem song) {
        songInfoPanel.setSongInfo(song);
    }

    private void setInfo(SlimPlaylistItem object) {
        setSongInfo(object);
    }

    public SlimPlaylist getPlaylist() {
        return playlist;
    }

    public void setPlaylist(SlimPlaylist playlist) {
        this.playlist = playlist;
    }

    public SlimPlayer getPlayer() {
        return player;
    }

    public void setPlayer(SlimPlayer player) {
        this.player = player;
    }

    @Override
    public void playlistChanged(PlaylistChangeEvent event) {
        try {
            switch (event.getId()) {
                case PlaylistChangeEvent.REPEAT_ITEM:
                case PlaylistChangeEvent.REPEAT_OFF:
                case PlaylistChangeEvent.REPEAT_PLAYLIST:
                    break;

                default:

                    final SlimPlaylistItem currentItem = getPlaylist().getCurrentItem();

                    if (currentItem == null) {
                        setSongInfo(null);
                        return;
                    }

                    setInfo(currentItem);
                    if (mainTabbedPane.getSelectedIndex() != PLAYLIST_TAB_INDEX) {

                        if (trayIcon != null) {
                            SlimPlaylistItem currentSong = (SlimPlaylistItem) currentItem;

                            trayIcon.displayMessage(currentSong.getArtist(),
                                    currentSong.getTitle(),
                                    TrayIcon.MessageType.INFO);

                            trayIcon.setToolTip("Bill's Jammin' Jukebox\n"
                                    + currentSong.getArtist() + "\n"
                                    + currentSong.getAlbum() + "\n"
                                    + currentSong.getTitle());
                        }
                    }
                    break;
            }

        } catch (SlimException ex) {
            Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void slimPlaylistChanged(PlaylistChangeEvent event) {
        boolean retract = false;
        switch (event.getId()) {
            case PlaylistChangeEvent.ITEM_ADDED:
            case PlaylistChangeEvent.ITEM_INSERTED:
            case PlaylistChangeEvent.ITEM_LOADED:
            case PlaylistChangeEvent.ALBUM_ADDED:
            case PlaylistChangeEvent.ARTIST_ADDED:
            case PlaylistChangeEvent.GENRE_ADDED:
                if (event.getSlimObject() != null) {
                    getRetractPanel().setInfo(event.getSlimObject(), event);
                } else if (event.getSlimObjects() != null) {
                    getRetractPanel().setInfo(event.getSlimObjects());
                }
                retract = true;
                break;
            case PlaylistChangeEvent.YEAR_ADDED:
                getRetractPanel().setYearInfo(event.getMessage());
                retract = true;
                break;
            default:
                break;
        }

        retractPanel(retract);
    }

    public SongRetractInfoPanel getRetractPanel() {
        return (SongRetractInfoPanel) songPanelRetract;
    }

    public boolean isRetracting() {
        return retracting;
    }

    public void setRetracting(boolean retracting) {
        this.retracting = retracting;
    }

    @Override
    public void dispose() {
        checkPlayer();
        super.dispose();
    }

    @Override
    public void windowClosing(java.awt.event.WindowEvent evt) {
        checkPlayer();
        System.exit(0);
    }

    @Override
    public void windowOpened(WindowEvent e) {
    }

    @Override
    public void windowClosed(WindowEvent e) {
        checkPlayer();
        System.exit(0);
    }

    @Override
    public void windowIconified(WindowEvent e) {
        if (!jp.isTrayAlways()) {
            if (jp.isTrayMin()) {
                minimizeToTray();
            }
        }
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }

    protected void minimizeToTray() {
        loadIntoTray();
    }    

    @Override
    public void settingsChanged(SettingsChangedEvent event) {
        if (currentPanelType != jp.getClientType()) {
            if (jp.getClientType() == JukeboxProperties.CLIENT_PLAYER_LEFT) {
                currentPanelType = JukeboxProperties.CLIENT_PLAYER_LEFT;
                createLeftPlayer(null);
            } else {
                try {
                    currentPanelType = JukeboxProperties.CLIENT_PLAYER_TOP;
                    createTopPanel(null);
                } catch (SlimException ex) {
                    Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    @Override
    public void playerChanged(PlayerChangeEvent event) {
        switch (event.getId()) {
            case PlayerChangeEvent.PLAYER_STARTED:
                try {
                    setInfo(getPlaylist().getCurrentItem());
                } catch (SlimException ex) {
                    Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                }
                break;
        }
    }

    public static void maximizePanel() {
        minimizePanel.setVisible(true);
        frame.setLocation(oldX, oldY);
        frame.setSize(oldSize);
    }

    public static void minimizePanel() {
        oldX = frame.getX();
        oldY = frame.getY();
        oldSize = frame.getSize();

        minimizePanel.setVisible(false);
        frame.pack();
    }

    @Override
    public boolean isMiniPlayer() {
        return !minimizePanel.isVisible();
    }

    @Override
    public void connectionChangeEventReceived(ConnectionChangeEvent event) {

        if (connectionErrorDialog == null) {
            connectionErrorDialog = new ConnectionErrorDialog(this);
        }

        if (event.isConnected()) {
            connectionErrorDialog.setVisible(false);
        } else {
            if (!connectionErrorDialog.isVisible()) {
                connectionErrorDialog.setVisible(true);
                connectionErrorDialog.toFront();
            }
        }
    }

    /**
     * @return the currentlyRetracting
     */
    public boolean isCurrentlyRetracting() {
        return currentlyRetracting;
    }

    /**
     * @param currentlyRetracting the currentlyRetracting to set
     */
    public void setCurrentlyRetracting(boolean currentlyRetracting) {
        this.currentlyRetracting = currentlyRetracting;
    }

    @Override
    public void favoritesChanged(FavoriteChangeEvent event) {
        switch (event.getId()) {
            case FavoriteChangeEvent.FAVORITE_ADDED:
                getRetractPanel().setFavoriteInfo(event.getTitle());
                retractPanel(true);
                break;
        }
    }

    private void retractPanel(boolean retract) {
        if (retract) {
            if (isRetracting()) {
                if (!isCurrentlyRetracting()) {
                    setCurrentlyRetracting(true);
                    retractPanel.toggle(true);

                    new Thread(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                Thread.sleep(5000);

                                if (isRetracting()) {
                                    retractPanel.toggle(true);
                                }
                            } catch (InterruptedException ex) {
                                Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                            } finally {
                                setCurrentlyRetracting(false);
                                retractPanel.setMinimized(true);
                            }
                        }
                    }).start();
                }
            }
        }
    }
    private static boolean loadedSongPanel;
    private static boolean loadedExplorerPanel;
    private static boolean loadedPlaylistManagerPanel;
    private static boolean loadedPlayerManagerPanel;
    private static boolean loadedAlbumPanel;
    private static boolean loadedFolderPanel;
    private static boolean loadedPlayerPanel;
    private static boolean loadedGuitarPanel;
    private static boolean loadedRadioPanel;
    private static boolean loadedFavPanel;
    private static boolean loadedNewMusicPanel;
    private static boolean loadedPodPanel;
    private static boolean loadedSearchPanel;
    private static boolean loadedPreferencesPanel;
    private static boolean loadedDatabaseProgressPanel;

    @Override
    public void lafChanged(LAFChangeEvent event) {
        try {
            UIManager.setLookAndFeel(StartUpProperties.getInstance().getLAFClassName());
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(StartupFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(StartupFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(StartupFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(StartupFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
        SwingUtilities.updateComponentTreeUI(this);
        pack();
    }

    @Override
    public void playerChosen(PlayerChosenEvent event) {
        try {
            setSongInfo(JukeboxProperties.getInstance().getPlaylist().getCurrentItem());
        } catch (Exception ex) {
            Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void playlistChanged(SavedPlaylistChangeEvent event) {
        boolean retract = false;
        switch (event.getId()) {
            case SavedPlaylistChangeEvent.ITEM_ADDED:
            case SavedPlaylistChangeEvent.YEAR_ADDED:
            case SavedPlaylistChangeEvent.ALBUM_ADDED:
            case SavedPlaylistChangeEvent.ARTIST_ADDED:
            case SavedPlaylistChangeEvent.GENRE_ADDED:
                getRetractPanel().setSavedPlaylistInfo(event);
                retract = true;
                break;
        }

        retractPanel(retract);
    }

    /**
     * @return the loaded
     */
    @Override
    public boolean isLoaded() {
        return loaded;
    }

    /**
     * @param loaded the loaded to set
     */
    private void setLoaded(boolean loaded) {
        this.loaded = loaded;
    }

    @Override
    public void positionWindow() {
        // set frame nicely in screen
        Toolkit tk = Toolkit.getDefaultToolkit();
        Dimension d = tk.getScreenSize();
        if (d.height >= 1024 && d.width >= 1400) {
            Rectangle rect = new Rectangle((int) (1400 / 1.05),
                    (int) (d.height / 1.05));
            setBounds(rect);

            int heightScreen = d.height / 2;
            int widthScreen = d.width / 2;
            setLocation(widthScreen - (int) (getWidth() / 2), heightScreen - (int) (getHeight() / 2));
        } else {
            setExtendedState(JFrame.MAXIMIZED_BOTH);
        }
    }

    private void disposeFrame() {
        dispose();
    }

    private void loadIntoTray() {
        if (SystemTray.isSupported()) {

            final SystemTray tray = SystemTray.getSystemTray();
            final Image image1 = Utils.createImageIcon(getClass(), "/resources/slimserver/bjjicontray.jpg", "icon image").getImage();

            MouseListener mouseListener = new MouseListener() {

                @Override
                public void mouseClicked(MouseEvent e) {
                }

                @Override
                public void mousePressed(MouseEvent e) {
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                }

                @Override
                public void mouseExited(MouseEvent e) {
                }
            };

            ActionListener exitListener = new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    disposeFrame();
                }
            };

            ActionListener stopListener = new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        getPlayer().stop();
                    } catch (SlimConnectionException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            };

            ActionListener pauseListener = new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        getPlayer().pause();
                    } catch (SlimConnectionException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            };

            ActionListener playListener = new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        getPlayer().play();
                    } catch (SlimConnectionException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            };

            ActionListener restoreListener = new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    setExtendedState(NORMAL);
                    setVisible(true);
                    requestFocus();
                    toFront();
                    if (!jp.isTrayAlways()) {
                        tray.remove(trayIcon);
                    }
                }
            };

            PopupMenu popup = new PopupMenu();
            MenuItem restoreItem = new MenuItem("Restore");
            restoreItem.addActionListener(restoreListener);
            MenuItem playItem = new MenuItem("Play");
            playItem.addActionListener(playListener);
            MenuItem pauseItem = new MenuItem("Pause");
            pauseItem.addActionListener(pauseListener);
            MenuItem stopItem = new MenuItem("Stop");
            stopItem.addActionListener(stopListener);
            MenuItem exitItem = new MenuItem("Exit");
            exitItem.addActionListener(exitListener);

            popup.add(restoreItem);
            popup.add(playItem);
            popup.add(pauseItem);
            popup.add(stopItem);
            popup.add(exitItem);

            trayIcon = new TrayIcon(image1, "Bill's Jammin' Jukebox", popup);

            ActionListener actionListener = new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    trayIcon.displayMessage("BJJ",
                            "Bill's Jammin' Jukebox",
                            TrayIcon.MessageType.INFO);
                }
            };

            trayIcon.setImageAutoSize(true);
            trayIcon.addActionListener(restoreListener);
            trayIcon.addMouseListener(mouseListener);

            try {
                tray.add(trayIcon);
            } catch (AWTException e) {
                System.err.println("TrayIcon could not be added.");
            }

            if (!jp.isTrayAlways()) {
                setVisible(false);
            }
        } else {
            //System Tray is not supported
        }
    }

    private void loadPlaylistManagerPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                int count = 0;
                while (!loadedExplorerPanel && count < 60) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        ++count;
                    }
                }

                try {
                    savedPlaylistPanel.add(new PlaylistManagerPanel(), BorderLayout.CENTER);
                } finally {
                    loadedPlaylistManagerPanel = true;
                }
            }
        }).start();
    }

    private void loadPlayerManagerPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                int count = 0;
                while (!loadedPlaylistManagerPanel && count < 60) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        ++count;
                    }
                }
                try {
                    playerTabPanel.add(new PlayerManagerPanel(), BorderLayout.CENTER);
                } finally {
                    loadedPlayerManagerPanel = true;
                }
            }
        }).start();
    }

    private void loadAlbumPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                int count = 0;
                while (!loadedPlayerManagerPanel && count < 60) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        ++count;
                    }
                }

                try {
                    if (jp.isShowCoverArt()) {
                        albumTabPanel.add(new AlbumCoverArtPanel(MusicObjects.getAlbums()));
                    } else {
                        albumTabPanel.add(new AlbumBrowserPanel(MusicObjects.getAlbums(true)));
                    }
                } catch (Exception ex) {
                    Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    loadedAlbumPanel = true;
                }
            }
        }).start();
    }

    private void loadNewMusicPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                int count = 0;
                while (!loadedAlbumPanel && count < 60) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                try {
                    if (jp.isShowCoverArt()) {
                        newMusicTabPanel.add(new AlbumCoverArtPanel(MusicObjects.getNewMusic()));
                    } else {
                        newMusicTabPanel.add(new AlbumBrowserPanel(MusicObjects.getNewMusic(true)));
                    }
                } catch (Exception ex) {
                    Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    loadedNewMusicPanel = true;
                }
            }
        }).start();
    }

    private void loadFolderPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                int count = 0;
                while (!loadedNewMusicPanel && count < 60) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        ++count;
                    }
                }

                try {
                    folderTabPanel.add(new FolderTreePanel(jp.getFolderBrowser(), jp.getPlaylist()));

                } catch (Exception ex) {
                    Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    loadedFolderPanel = true;
                }
            }
        }).start();
    }

    private void checkForUpdate() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    if (!jp.isVersionNotified()
                            && !jp.isDeveloper()
                            && !jp.isSnapShot()) {
                        if (!jp.getVersion().equalsIgnoreCase(jp.versionAvailable())) {
                            UpdateSplashDialog uss = new UpdateSplashDialog(parent, jp);
                            uss.setVisible(true);
                        }
                    } else {
                        if (jp.isDeveloper()) {
                            System.out.println("In developer mode, not checking for update.");
                        }
                    }
                } catch (Exception ex) {
                    Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }).start();
    }

    private void loadRetractPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                }
                retractPanel.install(parent,
                        parent.getWidth() - (int) songPanelRetract.getPreferredSize().getWidth() - 25,
                        parent.getHeight() - (int) songPanelRetract.getPreferredSize().getHeight() - 25);
            }
        }).start();
    }

    private void loadPlayerManagerMini() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
                gridBagConstraints.gridx = 0;
                gridBagConstraints.gridy = 0;
                gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
                jPanel6.add(new PlayerManagerPanelMini(), gridBagConstraints);
            }
        }).start();
    }

    private void loadFavoritesPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (!loadedRadioPanel) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                if (jp.isShowFavoritesPanel()) {
                    favoritesTabPanel.add(new FavoritesPanel(), BorderLayout.CENTER);
                } else {
                    mainTabbedPane.remove(favoritesTabPanel);
                }
                loadedFavPanel = true;
            }
        }).start();
    }

    private void loadRadiosPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (!loadedFavPanel) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                if (jp.isShowRadiosPanel()) {
                    radiosTabPanel.add(new RadioPanel(), BorderLayout.CENTER);
                } else {
                    mainTabbedPane.remove(radiosTabPanel);
                }
                loadedRadioPanel = true;
            }
        }).start();
    }

    private void loadPodcastPanel() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                int count = 0;
                while (!loadedFavPanel && count < 60) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainFramePlayer.class.getName()).log(Level.SEVERE, null, ex);
                    } finally {
                        ++count;
                    }
                }

                try {
                    if (jp.isShowPodcastPanel()) {
                        podcastTabPanel.add(new PodcastPanel(), BorderLayout.CENTER);
                    } else {
                        mainTabbedPane.remove(podcastTabPanel);
                    }
                } finally {
                    loadedPodPanel = true;
                }
            }
        }).start();
    }
}
